/*
 * Funkcijos darbui su išrikiuotu masyvu
 */
#include "../include/types.h"
#include "../include/errors.h"
#include "../include/ordarray.h"
#include "../include/kernelheap.h"
#include "../include/monitor.h"

/* Standartinė funkcija palyginimo */
s8int lt_predicate(type_t a, type_t b){
  return (a<b)?1:0;
}

/* Funkcijos skirtos sukurti išrikiuotam masyvui */

/* Bus naudojama kai heap'as bus sukurtas */
ord_arr_t create_arr(u32int max_size, lt_pred_t lessthan){
  ord_arr_t arr;
  arr.array = (void *)kmalloc(max_size*sizeof(type_t));
  memset(arr.array, 0, max_size*sizeof(type_t));
  arr.size = 0;
  arr.max_size = max_size;
  arr.lessthan = lessthan;
  return arr;
}
/* Kol heap'as nesukurtas, įrašinesim į nurodytą vietą */
ord_arr_t place_arr(void *addr, u32int max_size, lt_pred_t lessthan){
  ord_arr_t arr;
  
  arr.array = (type_t*)addr;
  memset(arr.array, 0, max_size*sizeof(type_t));
  arr.size = 0;
  arr.max_size = max_size;
  arr.lessthan = lessthan;
  return arr;
}

/* Sunaikinti išrikiuota masyvą */
void remove_arr(ord_arr_t *array){
  kfree(array->array); /* AR VEIKIA?! */
}
/* Pridėti elementą į masyvą */
void insert_arr(type_t elem, ord_arr_t *array){
  /* Patikriname ar įrašyta palyginimo funkcija */
  ASSERT(array->lessthan);
  u32int iterator = 0;
  
  /* Surandame į kurią vietą reikia talpinti naują elementą,
   * t.y. elementą prieš kurį turėtų stovėti naujasis elementas */
  while((iterator < array->size)&&(array->lessthan(array->array[iterator], elem))){
    iterator++;
  }
  
  if(iterator == array->size){ /* Jei vieta yra paskutinė */
    array->array[array->size++] = elem; /* Talpiname į galą */
  }
  else{
    type_t tmp = array->array[iterator]; /* Išsaudome dabartinę reikšmę toje vietoje */
    array->array[iterator] = elem; /* Įrašome naują elementą */
    /* Perstatome visus elementus masyvę, kurie eina po naujojo elemento */
    while(iterator < array->size){
      iterator++;
      type_t tmp2 = array->array[iterator];
      array->array[iterator] = tmp;
      tmp = tmp2;
    }
    array->size++; /* Padidiname esamą masyvo dydį */
  }
}

/* Rasti elementą pagal indeksą */
type_t find_arr(u32int index, ord_arr_t *array){
/* Patikriname ar indeksas nedidesnis nei dabartinis masyvo dydis */
  ASSERT(index < array->size); 
  return array->array[index];
}

/* Ištrinti elementą iš pasirinkto masyvo */
void remove_item(u32int index, ord_arr_t *array){
  /* Pašaliname norimą elementą ir visus elementus pertraukiame,
   * kad nebūtu tarpo */
  while(index < array->size){
    array->array[index] = array->array[index+1];
    index++;
  }
  array->size--; /* Sumažiname esamą masyvo dydį */
}
